home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1997 December
/
MACPOWER-1997-12.ISO.7z
/
MACPOWER-1997-12.ISO
/
AMUG
/
PROGRAMMING
/
Raven 1.2.sit
/
Raven 1.2
/
Source
/
Foundation
/
Common
/
ZGeometry.cpp
< prev
next >
Wrap
Text File
|
1997-07-24
|
9KB
|
333 lines
/*
* File: ZGeometry.h
* Summary: Point, size, and rectangle classes.
* Written by: Jesse Jones
*
* Copyright ゥ 1996-1997 Jesse Jones.
* For conditions of distribution and use, see copyright notice in ZTypes.h
*
* Change History (most recent first):
*
* <4> 6/17/97 JDJ TLongRect::MapTo uses longs instead of shorts.
* <3> 3/19/97 JDJ Pin methods pin to botRight instead of botRight
* minus one.
* <2> 3/11/97 JDJ Made Pin methods const.
* <1> 1/14/96 JDJ Created.
*/
#include <ZGeometry.h>
#include <Fp.h>
#include <ZNumbers.h>
//-----------------------------------
// Constants
//
const TPoint kZeroPt(0, 0);
const TSize kZeroSize(0, 0);
const TRect kZeroRect(0, 0, 0, 0);
const TLongPoint kLongZeroPt(0, 0);
const TLongSize kLongZeroSize(0, 0);
const TLongRect kLongZeroRect(0, 0, 0, 0);
//-----------------------------------
// STL specializations
//
DEFINE_STL_FUNCTIONS(TPoint);
DEFINE_STL_FUNCTIONS(TSize);
DEFINE_STL_FUNCTIONS(TRect);
DEFINE_STL_FUNCTIONS(TLongPoint);
DEFINE_STL_FUNCTIONS(TLongSize);
DEFINE_STL_FUNCTIONS(TLongRect);
// ===================================================================================
// class TPoint
// ===================================================================================
//---------------------------------------------------------------
//
// TPoint::operator*
//
//---------------------------------------------------------------
TPoint operator*(short num, const TPoint& pt)
{
return TPoint((short) (pt.h*num), (short) (pt.v*num));
}
#pragma mark -
// ===================================================================================
// class TSize
// ===================================================================================
//---------------------------------------------------------------
//
// TSize::operator*
//
//---------------------------------------------------------------
TSize operator*(short num, const TSize& size)
{
return TSize((short) (size.width*num), (short) (size.height*num));
}
#pragma mark -
// ===================================================================================
// class TRect
// ===================================================================================
//---------------------------------------------------------------
//
// TRect::operator|
//
//---------------------------------------------------------------
TRect TRect::operator|(const TRect& rect) const
{
TRect returnRect;
if (this->IsEmpty())
returnRect = rect;
else if (rect.IsEmpty())
returnRect = *this;
else {
returnRect.top = Min(top, rect.top);
returnRect.left = Min(left, rect.left);
returnRect.bottom = Max(bottom, rect.bottom);
returnRect.right = Max(right, rect.right);
}
return returnRect;
}
//---------------------------------------------------------------
//
// TRect::operator&
//
//---------------------------------------------------------------
TRect TRect::operator&(const TRect& rect) const
{
TRect returnRect;
returnRect.top = Max(top, rect.top);
returnRect.left = Max(left, rect.left);
returnRect.bottom = Min(bottom, rect.bottom);
returnRect.right = Min(right, rect.right);
if (left > right || top > bottom)
returnRect = kZeroRect;
return returnRect;
}
//---------------------------------------------------------------
//
// TRect::MapTo
//
//---------------------------------------------------------------
void TRect::MapTo(const TRect& container, double maxScaleFactor)
{
ASSERT(maxScaleFactor > 0.0);
short srcHeight = this->GetHeight();
short srcWidth = this->GetWidth();
short destHeight = container.GetHeight();
short destWidth = container.GetWidth();
double heightScale = (double) destHeight/srcHeight;
double widthScale = (double) destWidth/srcWidth;
double scale = (widthScale < heightScale) ? widthScale : heightScale;
double maxScale = sqrt(maxScaleFactor);
if (scale > maxScale)
scale = maxScale;
short aspectHeight = (short) (srcHeight*scale + 0.5);
short aspectWidth = (short) (srcWidth*scale + 0.5);
ASSERT(aspectHeight <= destHeight);
ASSERT(aspectWidth <= destWidth);
top = (short) ((container.top + container.bottom - aspectHeight)/2);
left = (short) ((container.left + container.right - aspectWidth)/2);
bottom = (short) (top + aspectHeight);
right = (short) (left + aspectWidth);
}
//---------------------------------------------------------------
//
// TRect::Pin
//
//---------------------------------------------------------------
TPoint TRect::Pin(const TPoint& pt) const
{
TPoint result = pt;
if (result.h < left)
result.h = left;
else if (result.h > right)
result.h = right;
if (result.v < top)
result.v = top;
else if (result.v > bottom)
result.v = bottom;
return result;
}
#pragma mark -
// ===================================================================================
// class TLongPoint
// ===================================================================================
//---------------------------------------------------------------
//
// TLongPoint::operator*
//
//---------------------------------------------------------------
TLongPoint operator*(long num, const TLongPoint& pt)
{
return TLongPoint(pt.h*num, pt.v*num);
}
// ===================================================================================
// class TLongSize
// ===================================================================================
//---------------------------------------------------------------
//
// TLongSize::operator*
//
//---------------------------------------------------------------
TLongSize operator*(long num, const TLongSize& size)
{
return TLongSize(size.width*num, size.height*num);
}
#pragma mark -
// ===================================================================================
// class TLongRect
// ===================================================================================
//---------------------------------------------------------------
//
// TLongRect::operator|
//
//---------------------------------------------------------------
TLongRect TLongRect::operator|(const TLongRect& rect) const
{
TLongRect returnRect;
if (this->IsEmpty())
returnRect = rect;
else if (rect.IsEmpty())
returnRect = *this;
else {
returnRect.top = Min(top, rect.top);
returnRect.left = Min(left, rect.left);
returnRect.bottom = Max(bottom, rect.bottom);
returnRect.right = Max(right, rect.right);
}
return returnRect;
}
//---------------------------------------------------------------
//
// TLongRect::operator&
//
//---------------------------------------------------------------
TLongRect TLongRect::operator&(const TLongRect& rect) const
{
TLongRect returnRect;
returnRect.top = Max(top, rect.top);
returnRect.left = Max(left, rect.left);
returnRect.bottom = Min(bottom, rect.bottom);
returnRect.right = Min(right, rect.right);
if (left > right || top > bottom)
returnRect = kLongZeroRect;
return returnRect;
}
//---------------------------------------------------------------
//
// TLongRect::MapTo
//
//---------------------------------------------------------------
void TLongRect::MapTo(const TRect& container, double maxScaleFactor)
{
ASSERT(maxScaleFactor > 0.0);
long srcHeight = this->GetHeight();
long srcWidth = this->GetWidth();
short destHeight = container.GetHeight();
short destWidth = container.GetWidth();
double heightScale = (double) destHeight/srcHeight;
double widthScale = (double) destWidth/srcWidth;
double scale = (widthScale < heightScale) ? widthScale : heightScale;
double maxScale = sqrt(maxScaleFactor);
if (scale > maxScale)
scale = maxScale;
long aspectHeight = (long) (srcHeight*scale + 0.5);
long aspectWidth = (long) (srcWidth*scale + 0.5);
ASSERT(aspectHeight <= destHeight);
ASSERT(aspectWidth <= destWidth);
top = (container.top + container.bottom - aspectHeight)/2;
left = (container.left + container.right - aspectWidth)/2;
bottom = top + aspectHeight;
right = left + aspectWidth;
}
//---------------------------------------------------------------
//
// TLongRect::Pin
//
//---------------------------------------------------------------
TLongPoint TLongRect::Pin(const TLongPoint& pt) const
{
TLongPoint result = pt;
if (result.h < left)
result.h = left;
else if (result.h > right)
result.h = right;
if (result.v < top)
result.v = top;
else if (result.v > bottom)
result.v = bottom;
return result;
}